<?php
ptaste();
require_once(dirname(__FILE__)."/interfaces.php");

class JEngXCombiner implements IJXmlProducer
{
	const HOW_REPLACE=0;
	const HOW_APPEND=1;
	const HOW_EVERYWHERE=0;
	const HOW_ONCE=2;
	public $dest=null;
	public $src=null;
	public $dest_node=null;
	public $src_node=null;
	public $how=null;
	public $logger=null;

	function __construct($dest,$src,$dest_node,$src_node="result",$how=0,$logger=null)
	{
//	  printf("conmbining %s with %s",$dest_node,$src_node);
	  $this->dest=$dest;
	  $this->src=$src;
	  $this->dest_node=$dest_node;
	  $this->src_node=$src_node;
	  $this->how=$how;
	  $this->logger=($logger)?$logger:new JEngNullLogger();
	}
	
	function prepare()
	{
	}
	
	function findNode($node,$name)
	{
		while($node)
		{
			if ($node->nodeName==$name)
			{
				$this->logger->debug("Node Found %s",$name);
				return $node;
			}
			if ($node->firstChild)
			{
				$nd=$this->findNode($node->firstChild,$name);
				if ($nd)
					return $nd;
			}
			$node=$node->nextSibling;
		 } 
		return false;
	}
	
	function replace_node($node,$name,$repl)
	{
		if (!$repl)
		  return null;
		$append=(($this->how & self::HOW_APPEND)!=0);
		$once=(($this->how & self::HOW_ONCE)!=0);
		while($node)
		{
		  if ($node->nodeName==$name)
		  {
			$xrepl=$this->dest->importNode($repl,true);
			$this->logger->debug("replacement found %s",$name);
		    if ($append)
			{
			  $nn=$xrepl->firstChild;
			  while($nn)
			  {
			    $xn=$nn->nextSibling;
				$node->appendChild($nn);
				$nn=$xn;
			  }
			}
			else{
				$pn=$node->parentNode;
				$nn=$xrepl->firstChild;
				$lst=$node->previousSibling;
				while($nn)
				{
					$lst=$nn;
					$xn=$nn->nextSibling;
					$this->logger->debug("placing node %s",$nn->nodeName);
					$pn->insertBefore($nn,$node);
					$nn=$xn;
				}
				$pn->removeChild($node);
				if (!$lst) $lst=$this->dest->documentElement;
				$node=$lst;
			}
		    if ($once) 
			{
				$this->logger->debug("once done xml is %s",$this->dest->saveXML());
				return;
			}
		  }
		  if ($node->firstChild)
				$this->replace_node($node->firstChild,$name,$repl);
		  $node=$node->nextSibling;
		}
	}
	
	function render()
	{
	  $this->prepare();
	  $this->replace_node($this->dest->documentElement,$this->dest_node,$this->findNode($this->src->documentElement,$this->src_node));
	  return $this->dest;
	}
	
	static function s_render()
	{
		$dest=func_get_arg(0);
		$src=func_get_arg(1);
		$dest_node=func_get_arg(2);
		$src_node="result";
		$lgr=null;
		$how=JEngXCombiner::HOW_REPLACE | JEngXCombiner::HOW_EVERYWHERE;
		if (func_num_args()>3)
		  $src_node=func_get_arg(3);
		if (func_num_args()>4)
		  $how=func_get_arg(4);
		if (func_num_args()>5)
		  $lgr=func_get_arg(5);
		$obj=new JEngXCombiner($dest,$src,$dest_node,$src_node,$how,$lgr);
		return $obj->render();
	}
}

?>